using System;
using System.IO;
using System.IO.Compression;
using System.Text;

namespace Icodeon.Util
{
    public sealed class GZipUtils : IZipUtils
    {
        public void ZipFiles(
            IObserver observer,
            DirectoryInfo inputDirectory,
            FileInfo zipFile,
            string password,
            int compressionLevel){

                this.ZipFile(inputDirectory.FullName, zipFile.FullName);
        }

        public void UnZipFiles(
            IObserver observer,
            FileInfo zipFile,
            DirectoryInfo outputDirectory,
            string password,
            bool deleteZipFile)
        {
            this.UnZipFile(zipFile.FullName, outputDirectory.FullName);
        }

        private void ZipFile(string sourceFile, string destinationFile){
            using (FileStream oldFile = File.OpenRead(sourceFile))
            using (FileStream newFile = File.Create(destinationFile))
            using (GZipStream compression = new GZipStream(newFile, CompressionMode.Compress))
            {
                byte[] buffer = new byte[1024];
                int numberOfBytesRead = oldFile.Read(buffer, 0, buffer.Length);
                while (numberOfBytesRead > 0)
                {
                    compression.Write(buffer, 0, numberOfBytesRead);
                    numberOfBytesRead = oldFile.Read(buffer, 0, buffer.Length);
                }
                compression.Close();
            }
        }

        private void UnZipFile(string sourceFile, string destinationFile)
        {
            using(FileStream compressFile = File.Open(sourceFile,FileMode.Open))
            using (FileStream uncompressedFile = File.Create(destinationFile))
            using (GZipStream compression = new GZipStream(compressFile,
                CompressionMode.Decompress))
                {
                int data = compression.ReadByte();
                while(data != -1)
                {
                    uncompressedFile.WriteByte((byte) data);
                    data = compression.ReadByte();
                }
                compression.Close();
            }
        }
    }
}
